home *** CD-ROM | disk | FTP | other *** search
/ Tech Win 1999 February / TECH Win 02-1999 Disc A.iso / ols / lzh / adminsd.lzh / SDOWN.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-16  |  7.9 KB  |  304 lines

  1. // SDown.cpp : アプリケーション用クラスの定義を行います。
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "SDown.h"
  6. #include "SDownDlg.h"
  7.  
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CSDownApp
  16.  
  17. BEGIN_MESSAGE_MAP(CSDownApp, CWinApp)
  18.     //{{AFX_MSG_MAP(CSDownApp)
  19.         // メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
  20.         //        この位置に生成されるコードを編集しないでください。
  21.     //}}AFX_MSG
  22.     ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  23. END_MESSAGE_MAP()
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CSDownApp クラスの構築
  27.  
  28. CSDownApp::CSDownApp()
  29. {
  30.     // TODO: この位置に構築用のコードを追加してください。
  31.     // ここに InitInstance 中の重要な初期化処理をすべて記述してください。
  32. }
  33.  
  34. /////////////////////////////////////////////////////////////////////////////
  35. // 唯一の CSDownApp オブジェクト
  36.  
  37. CSDownApp theApp;
  38.  
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CSDownApp クラスの初期化
  41.  
  42. BOOL CSDownApp::InitInstance()
  43. {
  44.     // 標準的な初期化処理
  45.     // もしこれらの機能を使用せず、実行ファイルのサイズを小さくしたけ
  46.     //  れば以下の特定の初期化ルーチンの中から不必要なものを削除して
  47.     //  ください。
  48.  
  49. #ifdef _AFXDLL
  50.     Enable3dControls();            // 共有 DLL 内で MFC を使う場合はここをコールしてください。
  51. #else
  52.     Enable3dControlsStatic();    // MFC と静的にリンクする場合はここをコールしてください。
  53. #endif
  54.  
  55.     CSDownDlg dlg;
  56.  
  57.     int nTime = 0;
  58.     int nOption = 0;
  59.     // Get commandline option
  60.     if( !GetAppOption( &nTime, &nOption))
  61.         return FALSE;
  62.  
  63.     int nResponse = IDOK;
  64.     
  65.     if( nTime > 0 )
  66.     {
  67.         dlg.m_nTime = nTime;
  68.         dlg.m_nOption = nOption;
  69.         m_pMainWnd = &dlg;
  70.         nResponse = dlg.DoModal();
  71.     }
  72.  
  73.     if (nResponse == IDOK)
  74.     {
  75.         // SE_SHUTDOWN_NAME権限をEnableし、NTをShutdownする
  76.         if( EnablePrivilege(SE_SHUTDOWN_NAME) )
  77.         {
  78.             // とりあえず先に書きこみをする。
  79.             Logging( _T("処理は正常に行われました。") );
  80.  
  81.             if (!ExitWindowsEx( nOption, 0 ))
  82.             {
  83.                 Logging(_T("シャットダウンは拒否されました。"));
  84.             }
  85.         }
  86.         else
  87.         {
  88.             Logging( _T("権限取得でエラーが発生しました。"));
  89.         }
  90.  
  91.         // SE_SHUTDOWN_NAME権限をDisable
  92.         DisablePrivilege(SE_SHUTDOWN_NAME);
  93.     }
  94.     else if (nResponse == IDCANCEL)
  95.     {
  96.         Logging(_T("シャットダウンは手動キャンセルされました。"));
  97.     }
  98.  
  99.     // ダイアログが閉じられてからアプリケーションのメッセージ ポンプを開始するよりは、
  100.     // アプリケーションを終了するために FALSE を返してください。
  101.     return FALSE;
  102. }
  103.  
  104. /////////////////////////////////////////////////////////////////////////////
  105. // 権限をEnableにする
  106. //   (パラメータにて渡された権限をEnableにする)
  107. /////////////////////////////////////////////////////////////////////////////
  108. BOOL    EnablePrivilege( LPTSTR privilege )
  109. {
  110.     // Non NT
  111.     OSVERSIONINFO ver;
  112.     ver.dwOSVersionInfoSize = sizeof( ver );
  113.     GetVersionEx( &ver );
  114.     if( ver.dwPlatformId  != VER_PLATFORM_WIN32_NT )
  115.         return TRUE;
  116.  
  117.     BOOL    bSuccess;
  118.     HANDLE    hToken;
  119.     LUID    luid;
  120.     TOKEN_PRIVILEGES    tokenPrivileges;
  121.  
  122.     // 本プロセスのアクセストークンを開いて変更可能にする
  123.     bSuccess = OpenProcessToken( GetCurrentProcess(), 
  124.                                  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  125.                                  &hToken);
  126.     if( !bSuccess ) {
  127.         //AfxMessageBox( "シャットダウンに失敗しました。\nOpenProcessToken()" );
  128.         return FALSE;
  129.     }
  130.  
  131.     // 権限に対する識別子を取得する
  132.     bSuccess = LookupPrivilegeValue( 0, privilege, &luid );
  133.     if( !bSuccess ) {
  134.         //AfxMessageBox( "シャットダウンに失敗しました。\nLookupPrivilegeValue()" );
  135.         return FALSE;
  136.     }
  137.     
  138.     // 権限をEnableにする
  139.     tokenPrivileges.PrivilegeCount = 1;
  140.     tokenPrivileges.Privileges[0].Luid = luid;
  141.     tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  142.     bSuccess = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, 0);
  143.  
  144.     // AdjustTokenPrivileges()は常にTRUEを返すのでGetLastError()にてチェックする
  145.     if( GetLastError() != ERROR_SUCCESS ) {
  146.         //AfxMessageBox( "シャットダウンに失敗しました。\nAdjustTokenPrivileges()" );
  147.         return FALSE;
  148.     }
  149.     return TRUE;
  150. }
  151.  
  152. /////////////////////////////////////////////////////////////////////////////
  153. // 権限をDisableする
  154. //   (パラメータにて渡された権限をDisableする)
  155. /////////////////////////////////////////////////////////////////////////////
  156. BOOL    DisablePrivilege( LPTSTR privilege )
  157. {
  158.     // Non NT
  159.     OSVERSIONINFO ver;
  160.     ver.dwOSVersionInfoSize = sizeof( ver );
  161.     GetVersionEx( &ver );
  162.     if( ver.dwPlatformId  != VER_PLATFORM_WIN32_NT )
  163.         return TRUE;
  164.  
  165.     BOOL    bSuccess;
  166.     HANDLE    hToken;
  167.     LUID    luid;
  168.     TOKEN_PRIVILEGES    tokenPrivileges;
  169.  
  170.     // 本プロセスのアクセストークンを開いて変更可能にする
  171.     bSuccess = OpenProcessToken( GetCurrentProcess(), 
  172.                                  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  173.                                  &hToken);
  174.     if( !bSuccess ) {
  175.         return FALSE;
  176.     }
  177.  
  178.     // 権限に対する識別子を取得する
  179.     bSuccess = LookupPrivilegeValue( 0, privilege, &luid );
  180.     if( !bSuccess ) {
  181.         bSuccess = LookupPrivilegeValue( 0, privilege, &luid );
  182.         return FALSE;
  183.     }
  184.  
  185.     // 権限をDisableする
  186.     tokenPrivileges.PrivilegeCount = 1;
  187.     tokenPrivileges.Privileges[0].Luid = luid;
  188.     tokenPrivileges.Privileges[0].Attributes = 0;
  189.     bSuccess = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, 0);
  190.  
  191.     // AdjustTokenPrivileges()は常にTRUEを返すのでGetLastError()にてチェックする
  192.     if( GetLastError() != ERROR_SUCCESS ) {
  193.         return FALSE;
  194.     }
  195.     return TRUE;
  196. }
  197.  
  198. /////////////////////////////////////////////////////////////////////////////
  199. // オプションを収得する
  200. /////////////////////////////////////////////////////////////////////////////
  201. BOOL CSDownApp::GetAppOption( int* pnTime, int* pnOption )
  202. {
  203.     // default value
  204.     *pnTime = 30;
  205.     *pnOption =     EWX_POWEROFF;
  206.  
  207.     char    string[256];
  208.     char    seps[] = " \t,";
  209.     char    *token;
  210.     int        nForce = 0;
  211.     
  212.     strncpy( string, (LPCTSTR)m_lpCmdLine, 255 );
  213.  
  214.     /* メッセージ大文字化 */
  215.     for( char *p = string; p < string + strlen( string ); p++ )
  216.     {
  217.         if( islower( *p ) )
  218.             *p = _toupper( *p );
  219.     }
  220.  
  221.     /* 最初のトークンを取得します。 */
  222.     token = strtok( string, seps );
  223.     while( token != NULL )
  224.     {
  225.         /* "string" にトークンがなくなるまで繰り返します。 */
  226.         // オプション
  227.         if( (token[0] == '/') || (token[0] == '-') )
  228.         {
  229.             // TIME
  230.             if( strcmp( &token[1], _T("T") ) == 0 )
  231.             {
  232.                 token = strtok( NULL, seps );
  233.                 *pnTime = atoi( token );
  234.                 if( *pnTime < 1 )
  235.                     *pnTime = 0;
  236.             }
  237.             // SHUTDOWN OPTION
  238.             else if( strcmp( &token[1], _T("PWOEROFF") ) == 0 )
  239.             {
  240.                 *pnOption = EWX_POWEROFF;
  241.             }
  242.             else if( strcmp( &token[1], _T("SHUTDOWN") ) == 0 )
  243.             {
  244.                 *pnOption = EWX_SHUTDOWN;
  245.             }
  246.             else if( strcmp( &token[1], _T("REBOOT") ) == 0 )
  247.             {
  248.                 *pnOption = EWX_REBOOT;
  249.             }
  250.             // FORCE COMMAND
  251.             else if( strcmp( &token[1], _T("F") ) == 0 )
  252.             {
  253.                 *pnOption |= nForce;
  254.             }
  255.  
  256.             // HELP
  257.             else if( strcmp( &token[1], _T("?") ) == 0 )
  258.             {
  259.                 AfxMessageBox( _T("usage:\n[/t]ime(sec.)]\n[/SHUTDOWN]or[/POWEROFF]or[/REBOOT]\n[/f]orce") );
  260.                 return FALSE;
  261.             }
  262.  
  263.             else
  264.             {
  265.                 AfxMessageBox( _T("option err\nTry /? option.") );
  266.                 return FALSE;
  267.             }
  268.         }
  269.         /* 次のトークンを取得します。 */
  270.         token = strtok( NULL, seps );
  271.     }
  272.     return TRUE;
  273. }
  274.  
  275. /////////////////////////////////////////////////////////////////////////////
  276. // ログを書きこむ
  277. /////////////////////////////////////////////////////////////////////////////
  278. BOOL Logging( char* msg )
  279. {
  280.     FILE *stream;
  281.     char logfile[MAX_PATH + 14];
  282.  
  283.     if( !GetWindowsDirectory( logfile, MAX_PATH ))
  284.         return FALSE;
  285.  
  286.     if( 0 == strcmp( &logfile[1], ":" ))
  287.         strcat( logfile, _T("ASDown.log") );
  288.     else
  289.         strcat( logfile, _T("\\ASDown.log") );
  290.  
  291.     if( (stream = fopen( logfile, "w+" )) == NULL )
  292.         return FALSE;
  293.  
  294.     // timestamp
  295.     time_t mytime;
  296.     time(&mytime);
  297.     fprintf(stream, _T("AdminShutDown at %s"), ctime(&mytime));
  298.  
  299.     fprintf( stream, msg );
  300.     fflush( stream );
  301.     fclose( stream );
  302.     return TRUE;
  303. }
  304.